package com.gsdx.klzn.result;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 响应信息主体
 *
 * @param <T> 数据类型
 */
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class R<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    private int code; // 状态码
    private String msg; // 返回消息
    private T data; // 返回数据

    // Getter 和 Setter 方法
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    /**
     * 成功返回，不带数据
     *
     * @return R<T>
     */
    public static <T> R<T> ok() {
        return restResult(null, 0, "成功");
    }

    /**
     * 成功返回，带数据
     *
     * @param data 返回数据
     * @return R<T>
     */
    public static <T> R<T> ok(T data) {
        return restResult(data, 0, "成功");
    }

    /**
     * 成功返回，带数据和自定义消息
     *
     * @param data 返回数据
     * @param msg  自定义消息
     * @return R<T>
     */
    public static <T> R<T> ok(T data, String msg) {
        return restResult(data, 0, msg);
    }

    /**
     * 失败返回，不带数据
     *
     * @return R<T>
     */
    public static <T> R<T> failed() {
        return restResult(null, 1, "失败");
    }

    /**
     * 失败返回，带自定义消息
     *
     * @param msg 自定义消息
     * @return R<T>
     */
    public static <T> R<T> failed(String msg) {
        return restResult(null, 1, msg);
    }

    /**
     * 失败返回，带数据
     *
     * @param data 返回数据
     * @return R<T>
     */
    public static <T> R<T> failed(T data) {
        return restResult(data, 1, "失败");
    }

    /**
     * 失败返回，带数据和自定义消息
     *
     * @param data 返回数据
     * @param msg  自定义消息
     * @return R<T>
     */
    public static <T> R<T> failed(T data, String msg) {
        return restResult(data, 1, msg);
    }

    /**
     * 构造返回结果
     *
     * @param data 返回数据
     * @param code 状态码
     * @param msg  返回消息
     * @return R<T>
     */
    private static <T> R<T> restResult(T data, int code, String msg) {
        R<T> result = new R<>();
        result.setCode(code);
        result.setData(data);
        result.setMsg(msg);
        return result;
    }

    /**
     * 判断是否成功
     *
     * @return boolean
     */
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    public boolean isOk() {
        return this.code == 0;
    }
}
